Skip to content

refactor(vanilla-epoll): extract shared emit_xcache helper for io_uring parity#968

Open
enghitalo wants to merge 1 commit into
MDA2AV:mainfrom
enghitalo:refactor/vanilla-epoll-shared-emit-xcache
Open

refactor(vanilla-epoll): extract shared emit_xcache helper for io_uring parity#968
enghitalo wants to merge 1 commit into
MDA2AV:mainfrom
enghitalo:refactor/vanilla-epoll-shared-emit-xcache

Conversation

@enghitalo

Copy link
Copy Markdown
Contributor

What & why

Small maintainability refactor, paired with the vanilla-io_uring convergence PR. vanilla-epoll inlined the crud X-Cache response framing in two places (the crud GET cache hit and miss paths). This folds both into one emit_xcache helper.

The helper is byte-identical to the code it replaces, and identical to the emit_xcache now used by the vanilla-io_uring twin — so both entries share one audited X-Cache framing and diff cleanly. vanilla-epoll remains the performance reference; this only removes duplication.

Supersedes #966 (same change, rebased clean onto current main).

Change

  • Add emit_xcache(mut out, ctype, body, cache) next to emit / write_resp.
  • Use it in start_crud_get (HIT) and render_crud_get (MISS).

No behavior or performance change.

Validation

Verified against a seeded Postgres that the crud GET MISS and HIT responses are byte-for-byte unchanged (and identical to the vanilla-io_uring twin, whose full-route byte-diff is in its PR).

🤖 Generated with Claude Code

…-Cache framing

Fold the two inlined X-Cache response framings (crud GET hit/miss) into one emit_xcache
helper — byte-identical output, and identical to the vanilla-io_uring twin's emit_xcache,
so both entries share one audited framing and diff cleanly. No behavior or performance
change (verified: crud GET MISS/HIT bytes unchanged).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@enghitalo

Copy link
Copy Markdown
Contributor Author

/benchmark -f vanilla-epoll

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

👋 /benchmark request received. A collaborator will review and approve the run.

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Benchmark Results

Framework: vanilla-epoll | Test: all tests

Test Conn RPS CPU Mem Δ RPS Δ Mem
baseline 512 3,705,301 6478.3% 76MiB -0.4% -2.6%
baseline 4096 4,114,801 6278.3% 153MiB -0.8% -3.8%
pipelined 512 39,877,942 6744.4% 75MiB +0.2% +2.7%
pipelined 4096 39,894,396 6741.7% 163MiB -0.3% -0.6%
limited-conn 512 1,003,091 3169.6% 68MiB +0.1% +1.5%
limited-conn 4096 1,006,779 3079.1% 70MiB -1.7% -1.4%
json 4096 2,136,644 6098.5% 168MiB -0.9% -11.6%
json-comp 512 2,111,528 6308.3% 86MiB +1.1% -9.5%
json-comp 4096 2,335,144 6434.0% 130MiB +0.5% -14.5%
json-comp 16384 2,323,307 5995.9% 123MiB +1.1% -52.9%
json-tls 4096 1,513,234 6062.1% 450MiB +0.8% +13.1%
upload 32 3,012 2121.2% 134MiB +1.8% ~0%
upload 256 3,003 3574.7% 330MiB -0.5% -2.4%
api-4 256 65,768 356.6% 109MiB +4.1% -2.7%
api-16 1024 252,073 1462.9% 166MiB +2.2% -9.8%
static 1024 1,835,388 5709.5% 98MiB +2.3% +1.0%
static 4096 1,815,735 5504.0% 224MiB +2.0% ~0%
static 6800 1,771,351 5240.0% 311MiB +2.1% -0.6%
async-db 1024 278,168 3017.2% 149MiB -3.3% +4.2%
crud 4096 308,376 782.6% 219MiB -0.8% +0.5%
fortunes 1024 166,731 5894.2% 257MiB -0.1% ~0%
Full log
  Templates: 20
  Expected:  200
  Duration:  15s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   11.58ms   1.07ms   34.60ms   73.20ms   111.20ms

  4687543 requests in 15.00s, 4687544 responses
  Throughput: 312.44K req/s
  Bandwidth:  94.22MB/s
  Status codes: 2xx=4625641, 3xx=0, 4xx=0, 5xx=61903
  Latency samples: 4687542 / 4687544 responses (100.0%)
  Reconnects: 21872
  Per-template: 98446,119630,154238,185209,216877,248599,276430,303381,320040,330384,339431,343757,342943,344211,345661,346481,128356,64083,82883,96502
  Per-template-ok: 95392,118285,152354,183058,214205,245515,273002,299602,316136,326407,335165,339557,338786,339946,341476,342052,128356,62084,80607,93654

  WARNING: 61903/4687544 responses (1.3%) had unexpected status (expected 2xx)
[info] CPU 782.6% | Mem 219MiB

[run 2/3]
gcannon v0.5.3
  Target:    localhost:8080/
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  1
  Req/conn:  200
  Templates: 20
  Expected:  200
  Duration:  15s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   12.27ms   5.52ms   35.10ms   67.90ms   98.40ms

  4490326 requests in 15.00s, 4490326 responses
  Throughput: 299.30K req/s
  Bandwidth:  92.14MB/s
  Status codes: 2xx=4418683, 3xx=0, 4xx=0, 5xx=71643
  Latency samples: 4490323 / 4490326 responses (100.0%)
  Reconnects: 20818
  Per-template: 100014,120993,151746,179739,208113,237288,264172,287916,302682,314280,317941,318849,319657,318084,318534,317891,149549,78914,87806,96155
  Per-template-ok: 96710,119482,149429,177128,204853,234030,260059,283583,298117,309491,312837,313786,314811,313240,313738,312869,149549,76538,84991,93439

  WARNING: 71643/4490326 responses (1.6%) had unexpected status (expected 2xx)
[info] CPU 780.7% | Mem 226MiB

[run 3/3]
gcannon v0.5.3
  Target:    localhost:8080/
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  1
  Req/conn:  200
  Templates: 20
  Expected:  200
  Duration:  15s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   13.18ms   8.16ms   34.40ms   62.50ms   88.60ms

  4211116 requests in 15.00s, 4211116 responses
  Throughput: 280.69K req/s
  Bandwidth:  86.84MB/s
  Status codes: 2xx=4153457, 3xx=0, 4xx=0, 5xx=57659
  Latency samples: 4211115 / 4211116 responses (100.0%)
  Reconnects: 19334
  Per-template: 104993,122157,148097,175184,203338,229215,252053,267533,279417,282438,283090,284239,286198,284350,286840,285966,149932,89723,92990,103362
  Per-template-ok: 102226,120730,145986,172794,200721,226164,248874,263989,275672,278612,279210,280328,282398,280627,282907,282104,149932,87951,91132,101099

  WARNING: 57659/4211116 responses (1.4%) had unexpected status (expected 2xx)
[info] CPU 760.5% | Mem 231MiB

=== Best: 308376 req/s (CPU: 782.6%, Mem: 219MiB) ===
[info] input BW: 26.47MB/s (avg template: 90 bytes)
[info] saved results/crud/4096/vanilla-epoll.json
httparena-bench-vanilla-epoll
httparena-bench-vanilla-epoll

==============================================
=== vanilla-epoll / fortunes / 1024c (tool=gcannon) ===
==============================================
[info] resetting postgres for a clean per-profile baseline
[info] starting postgres sidecar
httparena-postgres
[info] postgres ready (seeded)
[info] waiting for server...
[info] server ready

[run 1/3]
gcannon v0.5.3
  Target:    localhost:8080/fortunes
  Threads:   64
  Conns:     1024 (16/thread)
  Pipeline:  1
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   4.74ms   3.96ms   8.38ms   14.50ms   35.70ms

  833657 requests in 5.00s, 833657 responses
  Throughput: 166.66K req/s
  Bandwidth:  3.86GB/s
  Status codes: 2xx=833657, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 833657 / 833657 responses (100.0%)
[info] CPU 5894.2% | Mem 257MiB

[run 2/3]
gcannon v0.5.3
  Target:    localhost:8080/fortunes
  Threads:   64
  Conns:     1024 (16/thread)
  Pipeline:  1
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   4.71ms   4.05ms   8.53ms   12.90ms   16.90ms

  831410 requests in 5.00s, 831410 responses
  Throughput: 166.21K req/s
  Bandwidth:  3.85GB/s
  Status codes: 2xx=831410, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 831406 / 831410 responses (100.0%)
[info] CPU 6084.3% | Mem 256MiB

[run 3/3]
gcannon v0.5.3
  Target:    localhost:8080/fortunes
  Threads:   64
  Conns:     1024 (16/thread)
  Pipeline:  1
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   4.76ms   4.04ms   8.73ms   13.60ms   17.90ms

  821357 requests in 5.00s, 821357 responses
  Throughput: 164.21K req/s
  Bandwidth:  3.80GB/s
  Status codes: 2xx=821357, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 821351 / 821357 responses (100.0%)
[info] CPU 5947.2% | Mem 257MiB

=== Best: 166731 req/s (CPU: 5894.2%, Mem: 257MiB) ===
[info] saved results/fortunes/1024/vanilla-epoll.json
httparena-bench-vanilla-epoll
httparena-bench-vanilla-epoll
[info] skip: vanilla-epoll does not subscribe to baseline-h2
[info] skip: vanilla-epoll does not subscribe to static-h2
[info] skip: vanilla-epoll does not subscribe to baseline-h2c
[info] skip: vanilla-epoll does not subscribe to json-h2c
[info] skip: vanilla-epoll does not subscribe to baseline-h3
[info] skip: vanilla-epoll does not subscribe to static-h3
[info] skip: vanilla-epoll does not subscribe to gateway-64
[info] skip: vanilla-epoll does not subscribe to gateway-h3
[info] skip: vanilla-epoll does not subscribe to production-stack
[info] skip: vanilla-epoll does not subscribe to unary-grpc
[info] skip: vanilla-epoll does not subscribe to unary-grpc-tls
[info] skip: vanilla-epoll does not subscribe to stream-grpc
[info] skip: vanilla-epoll does not subscribe to stream-grpc-tls
[info] skip: vanilla-epoll does not subscribe to echo-ws
[info] skip: vanilla-epoll does not subscribe to echo-ws-pipeline
[info] rebuilding site/data/*.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/frameworks.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/api-16-1024.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/api-4-256.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/async-db-1024.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/baseline-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/baseline-512.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/crud-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/fortunes-1024.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/json-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/json-comp-16384.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/json-comp-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/json-comp-512.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/json-tls-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/limited-conn-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/limited-conn-512.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/pipelined-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/pipelined-512.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/static-1024.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/static-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/static-6800.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/upload-256.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/upload-32.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/current.json
[info] done
httparena-postgres
httparena-redis
[info] restoring loopback MTU to 65536

@enghitalo

Copy link
Copy Markdown
Contributor Author

/benchmark -f vanilla-epoll --save

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

👋 /benchmark request received. A collaborator will review and approve the run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant